package de.dailab.graphworld.bean;

import de.dailab.graphworld.bean.memory.Notifier;
import de.dailab.jiactng.agentcore.action.AbstractMethodExposingBean;
import de.dailab.jiactng.agentcore.action.Action;
import de.dailab.jiactng.agentcore.action.ActionResult;
import de.dailab.jiactng.agentcore.comm.ICommunicationAddress;
import de.dailab.jiactng.agentcore.comm.ICommunicationBean;
import de.dailab.jiactng.agentcore.comm.IGroupAddress;
import de.dailab.jiactng.agentcore.comm.message.JiacMessage;
import de.dailab.jiactng.agentcore.knowledge.IFact;
import de.dailab.jiactng.agentcore.ontology.IActionDescription;
import java.io.Serializable;
import java.util.Collection;

/**
 * An abstract implementation of a bean that provides communication
 * functionality.
 *
 * @author Kseniya
 */
public abstract class TeamMember extends AbstractMethodExposingBean implements Notifiable {

    private IActionDescription sendAction;
    private final Notifier notifier = new Notifier(this);
    //<editor-fold defaultstate="collapsed" desc="teamName prop">
    private String teamName;

    public String getTeamName() {
        return teamName;
    }

    public void setTeamName(String teamName) {
        this.teamName = teamName;
    }
    //</editor-fold>

    @Override
    public void doStart() {
        // join the communication group
        sendAction = this.retrieveAction(ICommunicationBean.ACTION_SEND);
        Action join = this.retrieveAction(ICommunicationBean.ACTION_JOIN_GROUP);
        for (IGroupAddress groupAddress : getGroups()) {
            this.invoke(join, new Serializable[]{groupAddress}, this);
        }
        this.memory.attach(notifier, new JiacMessage());
    }

    @Override
    public void doStop() {
        // leave the communication group
        Action leave = this.retrieveAction(ICommunicationBean.ACTION_LEAVE_GROUP);
        for (IGroupAddress groupAddress : getGroups()) {
            ActionResult result = this.invokeAndWaitForResult(leave, new Serializable[]{groupAddress});
            if (result.getFailure() != null) {
                this.log.error("could not leave chat group: " + result.getFailure());
            }
        }
        this.memory.detach(notifier);
    }

    @Override
    public void receiveResult(ActionResult result) {
        if (ICommunicationBean.ACTION_JOIN_GROUP.equals(result.getAction().getName())) {
            if (result.getFailure() != null) {
                this.log.error("could not join chat group address: " + result.getFailure());
            }
        }
    }

    protected final void sendMsgPersonal(IFact payload, ICommunicationAddress receiver) {
        JiacMessage transport = new JiacMessage(payload);
        invoke(sendAction, new Serializable[]{transport, receiver});
    }

    protected final void sendMsgGroup(IFact payload, IGroupAddress participants) {
        JiacMessage transport = new JiacMessage(payload);
        this.invoke(sendAction, new Serializable[]{transport, participants});
    }

    protected abstract Collection<IGroupAddress> getGroups();
}
